Sensor Fusion for Kinetis MCUs (ISSDK/KSDK version)
approximations.h File Reference
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

float fasin_deg (float x)
 
float facos_deg (float x)
 
float fatan_deg (float x)
 
float fatan2_deg (float y, float x)
 
float fatan_15deg (float x)
 

Detailed Description

Significant efficiencies were found by creating a set of trig functions which trade off precision for improved power/CPU performance. Full details are included in Application Note AN5015: Trigonometry Approximations

Definition in file approximations.h.

Function Documentation

float facos_deg ( float  x)

Definition at line 60 of file approximations.c.

Referenced by fAndroidAnglesDegFromRotationMatrix(), fNEDAnglesDegFromRotationMatrix(), and fWin8AnglesDegFromRotationMatrix().

61 {
62  // for robustness, check for invalid arguments
63  if (x >= 1.0F) return 0.0F;
64  if (x <= -1.0F) return 180.0F;
65 
66  // call the atan which will return an angle in the incorrect range -90 to 90 deg
67  // these lines cannot fail from division by zero or negative square root
68  if (x == 0.0F) return 90.0F;
69  if (x > 0.0F) return fatan_deg((sqrtf(1.0F - x * x) / x));
70  return 180.0F + fatan_deg((sqrtf(1.0F - x * x) / x));
71 }
float fatan_deg(float x)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

float fasin_deg ( float  x)

Definition at line 45 of file approximations.c.

Referenced by fAndroidAnglesDegFromRotationMatrix(), feCompassAndroid(), feCompassNED(), feCompassWin8(), fNEDAnglesDegFromRotationMatrix(), and fWin8AnglesDegFromRotationMatrix().

46 {
47  // for robustness, check for invalid argument
48  if (x >= 1.0F) return 90.0F;
49  if (x <= -1.0F) return -90.0F;
50 
51  // call the atan which will return an angle in the correct range -90 to 90 deg
52  // this line cannot fail from division by zero or negative square root since |x| < 1
53  return (fatan_deg(x / sqrtf(1.0F - x * x)));
54 }
float fatan_deg(float x)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

float fatan2_deg ( float  y,
float  x 
)

Definition at line 126 of file approximations.c.

Referenced by fAndroidAnglesDegFromRotationMatrix(), fNEDAnglesDegFromRotationMatrix(), and fWin8AnglesDegFromRotationMatrix().

127 {
128  // check for zero x to avoid division by zero
129  if (x == 0.0F)
130  {
131  // return 90 deg for positive y
132  if (y > 0.0F) return 90.0F;
133 
134  // return -90 deg for negative y
135  if (y < 0.0F) return -90.0F;
136 
137  // otherwise y= 0.0 and return 0 deg (invalid arguments)
138  return 0.0F;
139  }
140 
141  // from here onwards, x is guaranteed to be non-zero
142  // compute atan2 for quadrant 1 (0 to 90 deg) and quadrant 4 (-90 to 0 deg)
143  if (x > 0.0F) return (fatan_deg(y / x));
144 
145  // compute atan2 for quadrant 2 (90 to 180 deg)
146  if ((x < 0.0F) && (y > 0.0F)) return (180.0F + fatan_deg(y / x));
147 
148  // compute atan2 for quadrant 3 (-180 to -90 deg)
149  return (-180.0F + fatan_deg(y / x));
150 }
float fatan_deg(float x)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

float fatan_15deg ( float  x)

Definition at line 156 of file approximations.c.

Referenced by fatan_deg().

157 {
158  float x2; // x^2
159 #define PADE_A 96.644395816F // theoretical Pade[3/2] value is 5/3*180/PI=95.49296
160 #define PADE_B 25.086941612F // theoretical Pade[3/2] value is 4/9*180/PI=25.46479
161 #define PADE_C 1.6867633134F // theoretical Pade[3/2] value is 5/3=1.66667
162  // compute the approximation to the inverse tangent
163  // the function is anti-symmetric as required for positive and negative arguments
164  x2 = x * x;
165  return (x * (PADE_A + x2 * PADE_B) / (PADE_C + x2));
166 }
#define PADE_C
#define PADE_A
#define PADE_B

+ Here is the caller graph for this function:

float fatan_deg ( float  x)

Definition at line 76 of file approximations.c.

Referenced by facos_deg(), fasin_deg(), fatan2_deg(), and fWin8AnglesDegFromRotationMatrix().

77 {
78  float fangledeg; // compute computed (deg)
79  int8_t ixisnegative; // argument x is negative
80  int8_t ixexceeds1; // argument x is greater than 1.0
81  int8_t ixmapped; // argument in range tan(15 deg) to tan(45 deg)=1.0
82 #define TAN15DEG 0.26794919243F // tan(15 deg) = 2 - sqrt(3)
83 #define TAN30DEG 0.57735026919F // tan(30 deg) = 1/sqrt(3)
84  // reset all flags
85  ixisnegative = ixexceeds1 = ixmapped = 0;
86 
87  // test for negative argument to allow use of tan(-x)=-tan(x)
88  if (x < 0.0F)
89  {
90  x = -x;
91  ixisnegative = 1;
92  }
93 
94  // test for argument above 1 to allow use of atan(x)=pi/2-atan(1/x)
95  if (x > 1.0F)
96  {
97  x = 1.0F / x;
98  ixexceeds1 = 1;
99  }
100 
101  // at this point, x is in the range 0 to 1 inclusive
102  // map argument onto range -tan(15 deg) to tan(15 deg)
103  // using tan(angle-30deg) = (tan(angle)-tan(30deg)) / (1 + tan(angle)tan(30deg))
104  // tan(15deg) maps to tan(-15 deg) = -tan(15 deg)
105  // 1. maps to (sqrt(3) - 1) / (sqrt(3) + 1) = 2 - sqrt(3) = tan(15 deg)
106  if (x > TAN15DEG)
107  {
108  x = (x - TAN30DEG) / (1.0F + TAN30DEG * x);
109  ixmapped = 1;
110  }
111 
112  // call the atan estimator to obtain -15 deg <= angle <= 15 deg
113  fangledeg = fatan_15deg(x);
114 
115  // undo the distortions applied earlier to obtain -90 deg <= angle <= 90 deg
116  if (ixmapped) fangledeg += 30.0F;
117  if (ixexceeds1) fangledeg = 90.0F - fangledeg;
118  if (ixisnegative) fangledeg = -fangledeg;
119 
120  return (fangledeg);
121 }
#define TAN30DEG
float fatan_15deg(float x)
#define TAN15DEG

+ Here is the call graph for this function:

+ Here is the caller graph for this function: